//
//  ExceptionHandlingTest.m
//  test_simple_project
//
//  专门测试异常处理语法特性实现
//

#import "ExceptionHandlingTest.h"

@implementation ExceptionHandlingTest

- (void)basicExceptionHandling {
    @try {
        NSLog(@"Entering try block");
        [self throwRangeException];
    }
    @catch (NSException *exception) {
        NSLog(@"Caught exception: %@", exception.name);
    }
    @finally {
        NSLog(@"Finally block executed");
    }
}

- (void)nestedExceptionHandling {
    @try {
        NSLog(@"Outer try block");
        
        @try {
            NSLog(@"Inner try block");
            [self throwCustomException];
        }
        @catch (NSException *innerException) {
            NSLog(@"Inner catch: %@", innerException.name);
            @throw [NSException exceptionWithName:@"RethrowException" 
                                           reason:@"Rethrowing from inner catch" 
                                         userInfo:nil];
        }
        @finally {
            NSLog(@"Inner finally block");
        }
    }
    @catch (NSException *outerException) {
        NSLog(@"Outer catch: %@", outerException.name);
    }
    @finally {
        NSLog(@"Outer finally block");
    }
}

- (void)multipleExceptionTypes {
    @try {
        [self throwArgumentException];
    }
    @catch (NSException *exception) {
        if ([exception.name isEqualToString:NSRangeException]) {
            NSLog(@"Range exception: %@", exception.reason);
        } else if ([exception.name isEqualToString:NSInvalidArgumentException]) {
            NSLog(@"Argument exception: %@", exception.reason);
        } else {
            NSLog(@"General exception: %@", exception.name);
        }
    }
    @finally {
        NSLog(@"Multiple exception types finally");
    }
}

- (void)exceptionRethrowing {
    @try {
        @try {
            [self throwRangeException];
        }
        @catch (NSException *exception) {
            NSLog(@"Caught and rethrowing: %@", exception.name);
            @throw; // 重新抛出原异常
        }
    }
    @catch (NSException *rethrown) {
        NSLog(@"Caught rethrown exception: %@", rethrown.name);
    }
}

- (void)finallyBlockTesting {
    BOOL exceptionOccurred = NO;
    
    @try {
        NSLog(@"Try block with finally testing");
        [self throwCustomException];
    }
    @catch (NSException *exception) {
        NSLog(@"Exception caught: %@", exception.name);
        exceptionOccurred = YES;
    }
    @finally {
        NSLog(@"Finally block - exception occurred: %@", exceptionOccurred ? @"YES" : @"NO");
        // 清理代码
        NSLog(@"Performing cleanup in finally block");
    }
}

#pragma mark - Exception Throwing Methods

- (void)throwRangeException {
    NSArray *array = @[@"item1", @"item2"];
    // 故意访问越界索引来触发NSRangeException
    NSString *item = array[10];
    NSLog(@"This won't be printed: %@", item);
}

- (void)throwCustomException {
    @throw [NSException exceptionWithName:@"CustomTestException"
                                   reason:@"This is a custom test exception"
                                 userInfo:@{@"testKey": @"testValue"}];
}

- (void)throwArgumentException {
    @throw [NSException exceptionWithName:NSInvalidArgumentException
                                   reason:@"Invalid argument provided for testing"
                                 userInfo:nil];
}

@end
